﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DotNetNuke.Entities.Users;
using System.Xml.Linq;
using DotNetNuke.Security.Membership;
using DotNetNuke.Framework;
using DotNetNuke.Framework.Providers;
using System.Collections.Specialized;
using BrandonHaynes.Membership.Factors.PromptControls;
using System.Web.UI;

namespace BrandonHaynes.Membership.Factors
	{
	/// <summary>
	/// A factor that requires authentication against the ASP.NET membership system
	/// </summary>
	public sealed class MembershipFactor : IAuthenticationFactor
		{
		private MembershipProvider MembershipProvider { get; set; }
		private string AuthenticationType { get; set; }

		public MembershipFactor(IDictionary<string, string> attributes)
			: this(attributes.GetValueOrDefault("decorateProvider", "AspNetMembershipProvider"),
				attributes.GetValueOrDefault("authenticationType", "DNN"))
			{ }

		public MembershipFactor(string providerName, string authenticationType)
			: this(GetProviderByName(providerName), authenticationType)
			{ }

		public MembershipFactor(MembershipProvider membershipProvider, string authenticationType)
			{ 
			MembershipProvider = membershipProvider;
			AuthenticationType = authenticationType;
			}

		#region IAuthenticationFactor Members

		public string Name { get { return "Membership"; } }

		public void Authenticate(UserInfo user, Credential credential)
			{
			UserLoginStatus loginStatus = UserLoginStatus.LOGIN_FAILURE;

			// Authenticate the credential against the underlying ASP.NET membership subsystem
			MembershipProvider.UserLogin(credential.PortalId, user.Username, credential["password"], AuthenticationType, credential["ValidationCode"], ref loginStatus);
			credential.Status = loginStatus;
			}

		public Control PromptControl
			{ get { return new NullPrompt(); } }

		#endregion

		private static MembershipProvider GetProviderByName(string providerName)
			{ return (MembershipProvider)Reflection.CreateObject("members", providerName, string.Empty, string.Empty); }
		}
	}
